# -*- coding: utf-8 -*-
"""Controlador de Expresiones Regulares"""

from lex import model
from lex.lib.base import BaseController
from lex.model import metadata, DBSession
from lex.model.model import AnalizadorLexico, Alfabeto, ExpresionRegular
from lex.widgets import expresiones_form
from lex.widgets.expresiones_form import crear_expresion_form, \
    editar_expresion_form
from pylons.i18n import ugettext as _, lazy_ugettext as l_
from sqlalchemy import func
from sqlalchemy.exc import IntegrityError, SQLAlchemyError
from tg import expose, flash, require, url, request, redirect, tmpl_context, \
    validate
import transaction
from webhelpers import paginate

from repoze.what import predicates
from tgext.admin.controller import AdminController, AdminConfig
from tgext.admin.tgadminconfig import TGAdminConfig


__all__ = ['ExpresionesController']

class ExpresionesController(BaseController):

    @expose("lex.templates.expresiones.listado_expresiones")
    def listado_expresiones(self,id_analizador_lexico, page=1):
        """Metodo para listar las expresiones regulares correspondiente al Analizador seleccionado"""
        try:
            #Obtenemos todos los objetos "ExpresionRegular".
            expresiones = DBSession.query(ExpresionRegular).filter_by(id_analizador_lexico=id_analizador_lexico).order_by(ExpresionRegular.id_expresion_regular)
            currentPage = paginate.Page(expresiones, page, items_per_page=10)
        except SQLAlchemyError:
            flash(_("No se pudo acceder a Expresiones! SQLAlchemyError..."), 'error')
            redirect("/analizadores/listado_analizadores")
        except (AttributeError, NameError):
            flash(_("No se pudo acceder a Expresiones! Hay Problemas con el servidor..."), 'error')
            redirect("/analizadores/listado_analizadores")
    
        return dict(expresiones=currentPage.items, id_analizador_lexico=id_analizador_lexico, currentPage=currentPage)

    @expose('lex.templates.expresiones.nueva_expresion')
    def nueva_expresion(self, id_analizador_lexico, **kw):
        """Despliega el formulario para crear una nueva Expresion Regular"""
        try:
            #Establecemos el contexto de nuestro formulario de creacion de expresiones regulares.
            tmpl_context.form = crear_expresion_form
            kw['id_analizador_lexico'] = id_analizador_lexico
        except SQLAlchemyError:
            flash(_("No se pudo acceder a Creacion de Expresiones! SQLAlchemyError..."), 'error')
            redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)
        except (AttributeError, NameError):
            flash(_("No se pudo acceder a Creacion de Expresiones! Hay Problemas con el servidor..."), 'error')
            redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)

        return dict(nombre_modelo='Expresion Regular', id_analizador_lexico=id_analizador_lexico, value=kw)

    @validate(crear_expresion_form, error_handler=nueva_expresion)
    @expose()
    def add(self, **kw):
        """Metodo para insertar una Expresion Regular en la base de datos """
        try:
################################################################################
#Advertencia: Estas validaciones tambien se realizan en la funcion "update". Asi
#que, cualquier cambio realizado aqui, tambien debe considerarse si se realiza o
#no en la funcion "update".
######################### VALIDACION DEL NOMBRE ################################

            #Verificamos que la longitud del nombre sea mayor a uno.
            id_analizador_lexico = kw['id_analizador_lexico']
            nombre_expresion = kw['nombre_expresion_regular']
            lista_nombre = nombre_expresion.split()
            nombre = lista_nombre[0]
            expresiones = DBSession.query(ExpresionRegular).filter_by(id_analizador_lexico=id_analizador_lexico)

            if len(nombre) == 1:
               flash(_("El nombre debe tener mas de un caracter!"), 'error')
               redirect("/expresiones/nueva_expresion", id_analizador_lexico=id_analizador_lexico)

            #Verificamos que el nombre de la expresion regular sea unico.
            if expresiones != []:
               for expr in expresiones:
                   if lista_nombre[0] == expr.nombre_expresion_regular:
                      flash(_("El nombre ya existe!"), 'error')
                      redirect("/expresiones/nueva_expresion", id_analizador_lexico=id_analizador_lexico)
            
            nombre_expresion = lista_nombre[0] #Nombre final de la expresion.

######################### VALIDACION DE LA DEFINICION ##########################

            #Validamos la defincion de la expresion regular. Se debe verificar
            #que la expresion regular este definida de acuerdo al alfabeto
            #que corresponde al analizador lexico. Tambien se debe verificar
            #que si esta definido en funcion de otras expresiones regulares ya
            #creadas, entonces se debe verificar la validez. Se realizan las 
            #validaciones de los operadores, en cuanto a que si estan correctamente
            #ubicados en la definicion de la expresion regular.
            definicion_expresion = kw['definicion_expresion_regular']
            analizador_lexico = DBSession.query(AnalizadorLexico).get(id_analizador_lexico)
            lista_alfabetos = analizador_lexico.alfabetos
            lista_expresiones = DBSession.query(ExpresionRegular).filter_by(id_analizador_lexico=id_analizador_lexico)
            mi_alfabeto = []
            mis_expresiones = []
            mi_diccionario_alfa = {}
            mi_diccionario_expr = {}
            mi_diccionario_operadores = {"(":"(",")":")","*":"*","+":"+","?":"?",".":".","|":"|"}

            #OBTENCION DEL ALFABETO Y CREACION DE SU DICCIONARIO:
            #Agrupamos todos los alfabetos del analizador lexico correspondiente,
            #eliminamos los elementos duplicados y "creamos un diccionario" con
            #la lista resultante.
            if lista_alfabetos != []:
               for alfabeto in lista_alfabetos:
                   definicion_alfabeto = alfabeto.definicion_alfabeto
                   lista_simbolos = definicion_alfabeto.split()
                   for c in lista_simbolos:
                       mi_alfabeto.append(c) #Agrupacion de alfabetos.

               mi_alfabeto = list(set(mi_alfabeto)) #Eliminacion de duplicados.
               mi_diccionario_alfa = dict.fromkeys(mi_alfabeto) #Creacion del diccionario.
            else:
               flash(_("Su analizador lexico no dispone de Alfabeto!"), 'error')
               redirect("/expresiones/nueva_expresion", id_analizador_lexico=id_analizador_lexico)

            #OBTENCION DE LAS EXPRESIONES REGULARES Y CREACION DE SU DICCIONARIO:
            #"Creamos un diccionario" para la lista de nombres de expresiones regulares
            #pertenecientes al analizador lexico en cuestion.
            if lista_expresiones != []:
               for expresion in lista_expresiones:
                   mis_expresiones.append(expresion.nombre_expresion_regular)

               mi_diccionario_expr = dict.fromkeys(mis_expresiones) #Creacion del diccionario.
            else:
               flash(_("Su analizador lexico no dispone de Expresiones Regulares!"), 'error')
               redirect("/expresiones/nueva_expresion", id_analizador_lexico=id_analizador_lexico)

            #Con los dos diccionarios creados, debemos verificar que:
            # - Los simbolos que definen la expresion regular existan
            # - Los nombres de otras expresiones regulares, que son utilizadas
            #   para esta definicion, existan como parte de este analizador lexico
            sin_espacios = definicion_expresion.split()
            definicion_expresion = "".join(sin_espacios) #Definicion final de la expresion.

            #VALIDACION PRINCIPAL, DE SIMBOLOS, PALABRAS Y OPERADORES
            #Verificamos el comienzo de la expresion regular.
            if mi_diccionario_operadores.has_key(definicion_expresion[0]) and mi_diccionario_operadores.get(definicion_expresion[0])!="(":
               flash(_("La expresion no puede comenzar con  '" + definicion_expresion[0] + "' !"), 'error')
               redirect("/expresiones/nueva_expresion", id_analizador_lexico=id_analizador_lexico)

            #Verificamos el final de la expresion regular.
            if len(definicion_expresion) > 1:
               if mi_diccionario_operadores.has_key(definicion_expresion[len(definicion_expresion)-1]) and (mi_diccionario_operadores.get(definicion_expresion[len(definicion_expresion)-1])=="." or mi_diccionario_operadores.get(definicion_expresion[len(definicion_expresion)-1])=="|"):
                  flash(_("La expresion no puede terminar con  '" + definicion_expresion[len(definicion_expresion)-1] + "' !"), 'error')
                  redirect("/expresiones/nueva_expresion", id_analizador_lexico=id_analizador_lexico)

            #En este "while" se relizan las dos validaciones mas importantes, referentes
            #a los operadores y referentes a los simbolos y palabras.
            i = 0
            while i < len(definicion_expresion):
                c = definicion_expresion[i]
                #En este "if" se verifican las reglas referentes a los operadores
                if mi_diccionario_operadores.has_key(c):
                   #Condicion para el operador "("
                   if mi_diccionario_operadores.get(c) == "(":
                      k = i + 1
                      if k<len(definicion_expresion):
                         if mi_diccionario_operadores.has_key(definicion_expresion[k]) and mi_diccionario_operadores.get(definicion_expresion[k])!="(":
                            flash(_("Despues de '" + definicion_expresion[i] + "' no puede ir '" + definicion_expresion[k] + "'!"), 'error')
                            redirect("/expresiones/nueva_expresion", id_analizador_lexico=id_analizador_lexico)

                   #Condicion para el operador ")"
                   elif mi_diccionario_operadores.get(c) == ")":
                      k = i + 1
                      if k<len(definicion_expresion):
                         if not mi_diccionario_operadores.has_key(definicion_expresion[k]):
                            flash(_("Despues de '" + definicion_expresion[i] + "' debe ir un punto"), 'error')
                            redirect("/expresiones/nueva_expresion", id_analizador_lexico=id_analizador_lexico)

                   #Condicion para el operador punto.
                   elif mi_diccionario_operadores.get(c) == ".":
                      k = i + 1
                      if k<len(definicion_expresion):
                         if mi_diccionario_operadores.has_key(definicion_expresion[k]) and mi_diccionario_operadores.get(definicion_expresion[k])!="(":
                            flash(_("Despues de '" + definicion_expresion[i] + "' no puede ir '" + definicion_expresion[k] + "'!"), 'error')
                            redirect("/expresiones/nueva_expresion", id_analizador_lexico=id_analizador_lexico)
                   #Condicion para el operador de seleccion.
                   elif mi_diccionario_operadores.get(c) == "|":
                      k = i + 1
                      if k<len(definicion_expresion):
                         if mi_diccionario_operadores.has_key(definicion_expresion[k]) and mi_diccionario_operadores.get(definicion_expresion[k])!="(":
                            flash(_("Despues de '" + definicion_expresion[i] + "' no puede ir '" + definicion_expresion[k] + "'!"), 'error')
                            redirect("/expresiones/nueva_expresion", id_analizador_lexico=id_analizador_lexico)
                   #Condicion para el operador que no sea punto, ni parentesis, ni seleccion.
                   else:
                      k = i + 1
                      if k<len(definicion_expresion):
                         if mi_diccionario_operadores.has_key(definicion_expresion[k]) and mi_diccionario_operadores.get(definicion_expresion[k])!="." and mi_diccionario_operadores.get(definicion_expresion[k])!=")":
                            flash(_("Despues de '" + definicion_expresion[i] + "' no puede ir '" + definicion_expresion[k] + "'!"), 'error')
                            redirect("/expresiones/nueva_expresion", id_analizador_lexico=id_analizador_lexico)

                   i = i + 1
                #En este "else" se verifican que los simbolos pertenecen al alfabeto
                #y que las palabras sean definiciones existentes.
                else:
                   simbolo_o_palabra = c
                   j = i + 1
                   ban = False

                   if j<len(definicion_expresion):
                      while not mi_diccionario_operadores.has_key(definicion_expresion[j]):
                            simbolo_o_palabra = simbolo_o_palabra + definicion_expresion[j]
                            ban = True
                            i = i + 1
                            j = i + 1
                            if j<len(definicion_expresion):
                               pass
                            else:
                               break

                   #Se verifica si el simbolo existe en el alfabeto.
                   if ban==False:
                      if mi_diccionario_alfa.has_key(simbolo_o_palabra):
                         k = i + 1
                         if k<len(definicion_expresion):
                            if mi_diccionario_operadores.get(definicion_expresion[k])=="(":
                               flash(_("Despues de '" + definicion_expresion[i] + "' debe ir un punto!"), 'error')
                               redirect("/expresiones/nueva_expresion", id_analizador_lexico=id_analizador_lexico)
                      else:
                         flash(_("El simbolo '" +  simbolo_o_palabra + "' no existe!"), 'error')
                         redirect("/expresiones/nueva_expresion", id_analizador_lexico=id_analizador_lexico)

                   #Se verifica que la definicion de expresion regular exista.
                   else:
                      if mi_diccionario_expr.has_key(simbolo_o_palabra):
                         k = i + 1
                         if k<len(definicion_expresion):
                            if mi_diccionario_operadores.get(definicion_expresion[k])=="(":
                               flash(_("Despues de '" + definicion_expresion[i] + "' debe ir un punto!"), 'error')
                               redirect("/expresiones/nueva_expresion", id_analizador_lexico=id_analizador_lexico)
                      else:
                         flash(_("La expresion '" + simbolo_o_palabra + "' no existe!"), 'error')
                         redirect("/expresiones/nueva_expresion", id_analizador_lexico=id_analizador_lexico)

                   i = i + 1
################################################################################
            
            #Creamos una nueva expresion regular e insertamos en la BD.
            expresion = ExpresionRegular()
            expresion.id_analizador_lexico = id_analizador_lexico
            expresion.nombre_expresion_regular = nombre_expresion
            expresion.definicion_expresion_regular = definicion_expresion
            expresion.validado = True
            DBSession.add(expresion)
            DBSession.flush()

            #Actualizamos el estado del analizador lexico correspondiente.
            analizador_a_actualizar = DBSession.query(AnalizadorLexico).get(id_analizador_lexico)
            expresiones_afectadas = analizador_a_actualizar.expresiones_regulares

            validados = True
            if expresiones_afectadas != []:
               for expresion_afectada in expresiones_afectadas:
                   if expresion_afectada.validado == False:
                      validados = False
                      analizador_a_actualizar.estado = False
                      break
               if validados == True:
                  analizador_a_actualizar.estado = True
            else:
               analizador_a_actualizar.estado = False

            #Confirmamos la transaccion.
            DBSession.flush()
            transaction.commit()
        except IntegrityError:
            transaction.abort()
            flash(_("No se ha guardado! Hay Problemas con el servidor..."), 'error')
            redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)
        except SQLAlchemyError:
            flash(_("No se ha guardado! SQLAlchemyError..."), 'error')
            redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)
        except (AttributeError, NameError):
            flash(_("No se ha guardado! Hay Problemas con el servidor..."), 'error')
            redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)
        else:
            flash(_("Expresion creada!"), 'ok')
    
        redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)
      
    @expose('lex.templates.expresiones.editar_expresion')
    def editar_expresion(self, id_expresion_regular, **kw):
        """Metodo que rellena el formulario para editar los datos de una Expresion Regular"""
        try:
            #Establecemos el contexto del formulario de edicion de expresiones regulares.
            tmpl_context.form = editar_expresion_form

            #Cargamos el formulario con los datos de la expresion regular a editar.
            expresion = DBSession.query(ExpresionRegular).get(id_expresion_regular)
            kw['id_expresion_regular'] = expresion.id_expresion_regular
            kw['id_analizador_lexico'] = expresion.id_analizador_lexico
            id_analizador_lexico = expresion.id_analizador_lexico
            kw['nombre_expresion_regular'] = expresion.nombre_expresion_regular
            kw['definicion_expresion_regular'] = expresion.definicion_expresion_regular
            kw['validado'] = expresion.validado
        except SQLAlchemyError:
            flash(_("No se pudo acceder a Edicion de Expresiones! SQLAlchemyError..."), 'error')
            redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)
        except (AttributeError, NameError):
            flash(_("No se pudo acceder a Edicion de Expresiones! Hay Problemas con el servidor..."), 'error')
            redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)

        return dict(value=expresion, id_analizador_lexico=id_analizador_lexico)

    @validate(editar_expresion_form, error_handler=editar_expresion)
    @expose()
    def update(self, **kw):        
        """Metodo que actualizar la base de datos"""
        try:
################################################################################
#Advertencia: Estas validaciones tambien se realizan en la funcion "add". Asi
#que, cualquier cambio realizado aqui, tambien debe considerarse si se realiza o
#no en la funcion "add".
################################################################################

            #Establecemos algunas variables necesarias.
            id_expresion_regular = kw['id_expresion_regular']
            id_analizador_lexico = kw['id_analizador_lexico']
            nombre_expresion = kw['nombre_expresion_regular']

######################### VALIDACION DE LA DEFINICION ##########################

            #Validamos la defincion de la expresion regular. Se debe verificar
            #que la expresion regular este definida de acuerdo al alfabeto
            #que corresponde al analizador lexico. Tambien se debe verificar
            #que si esta definido en funcion de otras expresiones regulares ya
            #creadas, entonces se debe verificar la validez. Se realizan las 
            #validaciones de los operadores, en cuanto a que si estan correctamente
            #ubicados en la definicion de la expresion regular.
            definicion_expresion = kw['definicion_expresion_regular']
            analizador_lexico = DBSession.query(AnalizadorLexico).get(id_analizador_lexico)
            lista_alfabetos = analizador_lexico.alfabetos
            lista_expresiones = DBSession.query(ExpresionRegular).filter_by(id_analizador_lexico=id_analizador_lexico)
            mi_alfabeto = []
            mis_expresiones = []
            mi_diccionario_alfa = {}
            mi_diccionario_expr = {}
            mi_diccionario_operadores = {"(":"(",")":")","*":"*","+":"+","?":"?",".":".","|":"|"}

            #OBTENCION DEL ALFABETO Y CREACION DE SU DICCIONARIO:
            #Agrupamos todos los alfabetos del analizador lexico correspondiente,
            #eliminamos los elementos duplicados y "creamos un diccionario" con
            #la lista resultante.
            if lista_alfabetos != []:
               for alfabeto in lista_alfabetos:
                   definicion_alfabeto = alfabeto.definicion_alfabeto
                   lista_simbolos = definicion_alfabeto.split()
                   for c in lista_simbolos:
                       mi_alfabeto.append(c) #Agrupacion de alfabetos.

               mi_alfabeto = list(set(mi_alfabeto)) #Eliminacion de duplicados.
               mi_diccionario_alfa = dict.fromkeys(mi_alfabeto) #Creacion del diccionario.
            else:
               flash(_("Su analizador lexico no dispone de Alfabeto!"), 'error')
               redirect("/expresiones/editar_expresion", id_expresion_regular=id_expresion_regular)

            #OBTENCION DE LAS EXPRESIONES REGULARES Y CREACION DE SU DICCIONARIO:
            #"Creamos un diccionario" para la lista de nombres de expresiones regulares
            #pertenecientes al analizador lexico en cuestion.
            if lista_expresiones != []:
               for expresion in lista_expresiones:
                   mis_expresiones.append(expresion.nombre_expresion_regular)

               mi_diccionario_expr = dict.fromkeys(mis_expresiones) #Creacion del diccionario.
            else:
               flash(_("Su analizador lexico no dispone de Expresiones Regulares!"), 'error')
               redirect("/expresiones/editar_expresion", id_expresion_regular=id_expresion_regular)

            sin_espacios = definicion_expresion.split()
            definicion_expresion = "".join(sin_espacios) #Definicion final de la expresion.

            #VALIDACION PRINCIPAL, DE SIMBOLOS, PALABRAS Y OPERADORES
            #Verificamos el comienzo de la expresion regular.
            if mi_diccionario_operadores.has_key(definicion_expresion[0]) and mi_diccionario_operadores.get(definicion_expresion[0])!="(":
               flash(_("La expresion no puede comenzar con  '" + definicion_expresion[0] + "' !"), 'error')
               redirect("/expresiones/editar_expresion", id_expresion_regular=id_expresion_regular)

            #Verificamos el final de la expresion regular.
            if len(definicion_expresion) > 1:
               if mi_diccionario_operadores.has_key(definicion_expresion[len(definicion_expresion)-1]) and (mi_diccionario_operadores.get(definicion_expresion[len(definicion_expresion)-1])=="." or mi_diccionario_operadores.get(definicion_expresion[len(definicion_expresion)-1])=="|"):
                  flash(_("La expresion no puede terminar con  '" + definicion_expresion[len(definicion_expresion)-1] + "' !"), 'error')
                  redirect("/expresiones/editar_expresion", id_expresion_regular=id_expresion_regular)

            #En este "while" se relizan las dos validaciones mas importantes, referentes
            #a los operadores y referentes a los simbolos y palabras.
            i = 0
            while i < len(definicion_expresion):
                c = definicion_expresion[i]
                #En este "if" se verifican las reglas referentes a los operadores
                if mi_diccionario_operadores.has_key(c):
                   #Condicion para el operador "("
                   if mi_diccionario_operadores.get(c) == "(":
                      k = i + 1
                      if k<len(definicion_expresion):
                         if mi_diccionario_operadores.has_key(definicion_expresion[k]) and mi_diccionario_operadores.get(definicion_expresion[k])!="(":
                            flash(_("Despues de '" + definicion_expresion[i] + "' no puede ir '" + definicion_expresion[k] + "'!"), 'error')
                            redirect("/expresiones/editar_expresion", id_expresion_regular=id_expresion_regular)

                   #Condicion para el operador ")"
                   elif mi_diccionario_operadores.get(c) == ")":
                      k = i + 1
                      if k<len(definicion_expresion):
                         if not mi_diccionario_operadores.has_key(definicion_expresion[k]):
                            flash(_("Despues de '" + definicion_expresion[i] + "' debe ir un punto"), 'error')
                            redirect("/expresiones/editar_expresion", id_expresion_regular=id_expresion_regular)

                   #Condicion para el operador punto.
                   elif mi_diccionario_operadores.get(c) == ".":
                      k = i + 1
                      if k<len(definicion_expresion):
                         if mi_diccionario_operadores.has_key(definicion_expresion[k]) and mi_diccionario_operadores.get(definicion_expresion[k])!="(":
                            flash(_("Despues de '" + definicion_expresion[i] + "' no puede ir '" + definicion_expresion[k] + "'!"), 'error')
                            redirect("/expresiones/editar_expresion", id_expresion_regular=id_expresion_regular)
                   #Condicion para el operador de seleccion.
                   elif mi_diccionario_operadores.get(c) == "|":
                      k = i + 1
                      if k<len(definicion_expresion):
                         if mi_diccionario_operadores.has_key(definicion_expresion[k]) and mi_diccionario_operadores.get(definicion_expresion[k])!="(":
                            flash(_("Despues de '" + definicion_expresion[i] + "' no puede ir '" + definicion_expresion[k] + "'!"), 'error')
                            redirect("/expresiones/editar_expresion", id_expresion_regular=id_expresion_regular)
                   #Condicion para el operador que no sea punto, ni parentesis, ni seleccion.
                   else:
                      k = i + 1
                      if k<len(definicion_expresion):
                         if mi_diccionario_operadores.has_key(definicion_expresion[k]) and mi_diccionario_operadores.get(definicion_expresion[k])!="." and mi_diccionario_operadores.get(definicion_expresion[k])!=")":
                            flash(_("Despues de '" + definicion_expresion[i] + "' no puede ir '" + definicion_expresion[k] + "'!"), 'error')
                            redirect("/expresiones/editar_expresion", id_expresion_regular=id_expresion_regular)

                   i = i + 1
                #En este "else" se verifican que los simbolos pertenecen al alfabeto
                #y que las palabras sean definiciones existentes.
                else:
                   simbolo_o_palabra = c
                   j = i + 1
                   ban = False

                   if j<len(definicion_expresion):
                      while not mi_diccionario_operadores.has_key(definicion_expresion[j]):
                            simbolo_o_palabra = simbolo_o_palabra + definicion_expresion[j]
                            i = i + 1
                            j = i + 1
                            ban = True
                            if j<len(definicion_expresion):
                               pass
                            else:
                               break

                   #Se verifica si el simbolo existe en el alfabeto.
                   if ban==False:
                      if mi_diccionario_alfa.has_key(simbolo_o_palabra):
                         k = i + 1
                         if k<len(definicion_expresion):
                            if mi_diccionario_operadores.get(definicion_expresion[k])=="(":
                               flash(_("Despues de '" + definicion_expresion[i] + "' debe ir un punto!"), 'error')
                               redirect("/expresiones/editar_expresion", id_expresion_regular=id_expresion_regular)
                      else:
                         flash(_("El simbolo '" +  simbolo_o_palabra + "' no existe!"), 'error')
                         redirect("/expresiones/editar_expresion", id_expresion_regular=id_expresion_regular)
                   #Se verifica que la definicion de expresion regular exista y que no se trate de una definicion recursiva.
                   else:
                      if mi_diccionario_expr.has_key(simbolo_o_palabra) and simbolo_o_palabra!=nombre_expresion:
                         k = i + 1
                         if k<len(definicion_expresion):
                            if mi_diccionario_operadores.get(definicion_expresion[k])=="(":
                               flash(_("Despues de '" + definicion_expresion[i] + "' debe ir un punto!"), 'error')
                               redirect("/expresiones/editar_expresion", id_expresion_regular=id_expresion_regular)
                      else:
                         #Verificamos si se trata de una definicion recursiva.
                         if simbolo_o_palabra==nombre_expresion:
                            flash(_("Las definiciones recursivas no estan permitidas!"), 'error')
                            redirect("/expresiones/editar_expresion", id_expresion_regular=id_expresion_regular)
                         #Verificamos si se trata de una definicion que no existe.
                         else:
                            flash(_("La expresion '" + simbolo_o_palabra + "' no existe!"), 'error')
                            redirect("/expresiones/editar_expresion", id_expresion_regular=id_expresion_regular)

                   i = i + 1
################################################################################


            #Se deben eliminar los afn, afd y afdOptimizado relacionados al analizador
            ###########################


            ############################


            #Guardamos los cambios realizados en la edicion de la expresion regular.
            #Solo permitimos editar la definicion de la expresion regular,
            #para que el nombre se mantenga de modo que no afecte a otras
            #definiciones que la utilizan.
            expresion = DBSession.query(ExpresionRegular).get(id_expresion_regular)
            expresion.definicion_expresion_regular = definicion_expresion
            expresion.validado = True
            DBSession.flush()

            #Actualizamos el estado del analizador lexico correspondiente.
            analizador_a_actualizar = DBSession.query(AnalizadorLexico).get(id_analizador_lexico)
            expresiones_afectadas = analizador_a_actualizar.expresiones_regulares

            validados = True
            if expresiones_afectadas != []:
               for expresion_afectada in expresiones_afectadas:
                   if expresion_afectada.validado == False:
                      validados = False
                      analizador_a_actualizar.estado = False
                      break
               if validados == True:
                  analizador_a_actualizar.estado = True
            else:
               analizador_a_actualizar.estado = False

            #Confirmamos la transaccion.
            DBSession.flush()
            transaction.commit()
        except IntegrityError:
            transaction.abort()
            flash(_("No se han guardado los cambios! Hay Problemas con el servidor..."), 'error')
            redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)
        except SQLAlchemyError:
            flash(_("No se han guardado los cambios! SQLAlchemyError..."), 'error')
            redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)
        except (AttributeError, NameError):
            flash(_("No se han guardado los cambios! Hay Problemas con el servidor..."), 'error')
            redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)
        else:
            flash(_("Se han guardado los cambios!"), 'ok')

        redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)

    @expose('lex.templates.expresiones.confirmar_eliminar_expresion')
    def confirmar_eliminar_expresion(self, id_expresion_regular, **kw):
        """Despliega confirmacion de eliminacion"""
        try:
            #Se muestran los datos de la expresion regular seleccionada.
            expresion = DBSession.query(ExpresionRegular).get(id_expresion_regular)
            id_analizador_lexico = expresion.id_analizador_lexico
        except SQLAlchemyError:
            flash(_("No se pudo acceder a Eliminacion de Analizadores! SQLAlchemyError..."), 'error')
            redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)
        except (AttributeError, NameError):
            flash(_("No se pudo acceder a Eliminacion de Analizadores! Hay Problemas con el servidor..."), 'error')
            redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)

        return dict(value=expresion)

    @expose()
    def delete(self, id_analizador_lexico, id_expresion_regular, **kw):
        """Metodo que elimina la expresion regular de la base de datos"""
        try:
            #Al eliminar una expresion regular se deben eliminar los afn, afd y afdOptimizado relacionados
            #Se debe cambiar el estado de las expresiones regulares que utilizaban la expresion regular eliminada.
####################


####################
            #Realizamos la eliminacion de la expresion regular.
            DBSession.delete(DBSession.query(ExpresionRegular).get(id_expresion_regular))
            DBSession.flush()

            #En el analizador afectado, establecemos a "False" el campo 
            #"validado" de sus expresiones regulares restantes. Tambien 
            #establecemos a "False" el campo "estado" del analizador afectado.
            analizador_afectado = DBSession.query(AnalizadorLexico).get(id_analizador_lexico)
            expresiones_afectadas = analizador_afectado.expresiones_regulares

            if expresiones_afectadas != []:
               for expresion_afectada in expresiones_afectadas:
                   expresion_afectada.validado = False
            analizador_afectado.estado = False

            #Confirmamos la transaccion.
            DBSession.flush()
            transaction.commit()
        except IntegrityError:
            transaction.abort()
            flash(_("No se ha eliminado! Hay Problemas con el servidor..."), 'error')
            redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)
        except SQLAlchemyError:
            flash(_("No se ha eliminado! SQLAlchemyError..."), 'error')
            redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)
        except (AttributeError, NameError):
            flash(_("No se ha eliminado! Hay Problemas con el servidor..."), 'error')
            redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)
        else:
            flash(_("Expresion eliminada!"), 'ok')

        redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)

